package com.zhuangjie.shop.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zhaungjie.base.utils.SyncSort;
import com.zhaungjie.base.utils.PropertiesCopyUtils.PropertiesCopy;
import com.zhuangjie.base.constant.CommonSeparatorConstants;
import com.zhuangjie.shop.constant.ActivityConstant;
import com.zhuangjie.shop.dto.activity.FullReductionActivityDTO;
import com.zhuangjie.shop.dto.activity.NewCustomerActivityDTO;
import com.zhuangjie.shop.dto.activity.ReduceDeliveryFreeActivityDTO;
import com.zhuangjie.shop.entity.ShopActivityInstance;
import com.zhuangjie.shop.enums.ActivityType;
import com.zhuangjie.shop.enums.ActivityValueType;
import com.zhuangjie.shop.enums.ReduceValueType;
import com.zhuangjie.shop.enums.ActivityRequireUserEnum;
import com.zhuangjie.shop.helper.ShopModuleTokenDataProvider;
import com.zhuangjie.shop.mapper.ShopActivityInstanceMapper;
import com.zhuangjie.shop.service.ShopActivityInstanceService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.RoundingMode;
import java.text.NumberFormat;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author zhuangjie
 * @since 2024-03-12
 */
@Service
public class ShopActivityInstanceServiceImpl extends ServiceImpl<ShopActivityInstanceMapper, ShopActivityInstance> implements ShopActivityInstanceService {


    /**
     * Double值格式化器（不要无意义小数）
     */
    private final NumberFormat nf = NumberFormat.getInstance();
    {
        // 格式化数字类型不显示无意义小数点
        nf.setRoundingMode(RoundingMode.DOWN);
        nf.setMaximumFractionDigits(2);
    }

    @Override
    public List<ShopActivityInstance> getShopActivityListByType(Long activityTypeId) {
        LambdaQueryWrapper<ShopActivityInstance> querySpecifyTypeActivityWrapper = Wrappers.lambdaQuery(ShopActivityInstance.class)
                .eq(ShopActivityInstance::getShopId, ShopModuleTokenDataProvider.getShopId())
                .eq(ShopActivityInstance::getActivityId, activityTypeId);
        return this.list(querySpecifyTypeActivityWrapper);
    }


    @Override
    public void putFullReductionActivity(FullReductionActivityDTO fullReductionActivityDTO) {
        if (fullReductionActivityDTO.getEndDate() != null && fullReductionActivityDTO.getStartDate().isAfter(fullReductionActivityDTO.getEndDate())) {
            throw new IllegalArgumentException("结束时间不能早于开始时间");
        }
        ShopActivityInstance shopActivityInstanceForDB = PropertiesCopy.type(FullReductionActivityDTO.class, ShopActivityInstance.class)
                .produce(fullReductionActivityDTO);
        // 设置满减特有/固有值
        shopActivityInstanceForDB.setActivityId(ActivityType.FULL_REDUCTION.getCode());
        shopActivityInstanceForDB.setShopId(ShopModuleTokenDataProvider.getShopId());
        shopActivityInstanceForDB.setTitle(generateFullReductionActivityName(fullReductionActivityDTO));
        shopActivityInstanceForDB.setValueType(ActivityValueType.BY_ACTIVITY_FEATURE.getCode());
        shopActivityInstanceForDB.setCustomerType(ActivityRequireUserEnum.ALL_USERS.getCode());
        // 根据id判断是更新还是插入
        if (shopActivityInstanceForDB.getId() != null) {
            this.updateById(shopActivityInstanceForDB);
        }else {
            this.save(shopActivityInstanceForDB);
        }
    }

    @Override
    public void removeShopActivityInstanceById(Long activityInstanceId) {
        LambdaQueryWrapper<ShopActivityInstance> removeActivityInstanceWrapper = Wrappers.lambdaQuery(ShopActivityInstance.class)
                .eq(ShopActivityInstance::getShopId, ShopModuleTokenDataProvider.getShopId())
                .eq(ShopActivityInstance::getId, activityInstanceId);
        boolean isRemoveSuccess = this.remove(removeActivityInstanceWrapper);
        if (!isRemoveSuccess) {
            throw new IllegalArgumentException("删除活动实例失败");
        }
    }

    @Override
    public ShopActivityInstance getShopActivityInstanceById(Long activityInstanceId) {
        LambdaQueryWrapper<ShopActivityInstance> removeActivityInstanceWrapper = Wrappers.lambdaQuery(ShopActivityInstance.class)
                .eq(ShopActivityInstance::getShopId, ShopModuleTokenDataProvider.getShopId())
                .eq(ShopActivityInstance::getId, activityInstanceId);
        return this.getOne(removeActivityInstanceWrapper);
    }

    @Override
    public void putNewCustomerActivity(NewCustomerActivityDTO newCustomerActivityDTO) {
        ShopActivityInstance shopActivityInstanceForDB = PropertiesCopy.type(NewCustomerActivityDTO.class, ShopActivityInstance.class)
                .produce(newCustomerActivityDTO);
        // 进行活动固定属性的设定
        shopActivityInstanceForDB.setShopId(ShopModuleTokenDataProvider.getShopId());
        shopActivityInstanceForDB.setActivityId(ActivityType.NEW_CUSTOMER_DISCOUNT.getCode());
        shopActivityInstanceForDB.setCustomerType(ActivityRequireUserEnum.ALL_USERS.getCode());
        shopActivityInstanceForDB.setTitle("新客立减"+newCustomerActivityDTO.getValue()+"元");
        shopActivityInstanceForDB.setValueType(ActivityValueType.BY_AMOUNT.getCode());
        if (shopActivityInstanceForDB.getId() != null) {
            this.updateById(shopActivityInstanceForDB);
        }else {
            this.save(shopActivityInstanceForDB);
        }
    }

    @Override
    public void putReduceDeliveryFreeActivity(ReduceDeliveryFreeActivityDTO reduceDeliveryFreeActivityDTO) {
        // 1. 值检查
        if (reduceDeliveryFreeActivityDTO.getEndDate() != null && reduceDeliveryFreeActivityDTO.getStartDate().isAfter(reduceDeliveryFreeActivityDTO.getEndDate())) {
            throw new IllegalArgumentException("结束时间不能早于开始时间");
        }
        if (Objects.equals(ReduceValueType.BY_AMOUNT.getCode(), reduceDeliveryFreeActivityDTO.getValueType())) {
            // - 统一立减类型，值只能大于0的数值类型
            if (Double.parseDouble(reduceDeliveryFreeActivityDTO.getValue()) <= 0) {
                throw new IllegalArgumentException("立减配送费活动值必须大于0");
            }
        }else if(Objects.equals(ReduceValueType.ACTIVITY_FEATURE.getCode(), reduceDeliveryFreeActivityDTO.getValueType())) {
            // - 按距离减类型
            // 不为空检查
            if (reduceDeliveryFreeActivityDTO.getThreshold() == null || reduceDeliveryFreeActivityDTO.getValue() == null) {
                throw new IllegalArgumentException("按距离减距离与优惠值都不应为空！");
            }
            // 阶梯对齐
            if (reduceDeliveryFreeActivityDTO.getThreshold().split(CommonSeparatorConstants.MULTIPLE_SEPARATOR).length != reduceDeliveryFreeActivityDTO.getValue().split(CommonSeparatorConstants.MULTIPLE_SEPARATOR).length) {
                throw new IllegalArgumentException("立减配送费活动值与距离值数量不一致！");
            }
        }else {
            throw new RuntimeException("立减配送费活动值类型错误！");
        }
        // 2. 添加
        ShopActivityInstance shopActivityInstanceForDB = PropertiesCopy.type(ReduceDeliveryFreeActivityDTO.class, ShopActivityInstance.class)
                .produce(reduceDeliveryFreeActivityDTO);
        // 设置满减特有/固有值
        shopActivityInstanceForDB.setActivityId(ActivityType.DELIVERY_FEE_DISCOUNT.getCode());
        shopActivityInstanceForDB.setShopId(ShopModuleTokenDataProvider.getShopId());
        shopActivityInstanceForDB.setTitle(generateReduceDeliveryFreeActivityName(reduceDeliveryFreeActivityDTO));
        shopActivityInstanceForDB.setCustomerType(ActivityRequireUserEnum.ALL_USERS.getCode());
        // 根据id判断是更新还是插入
        if (shopActivityInstanceForDB.getId() != null) {
            this.updateById(shopActivityInstanceForDB);
        }else {
            this.save(shopActivityInstanceForDB);
        }
    }

    @Override
    @Transactional
    public void participateOrExitDivineVoucher(Boolean isParticipate) {
        LambdaQueryWrapper<ShopActivityInstance> exitDivineVoucherWrapper = Wrappers.lambdaQuery(ShopActivityInstance.class)
                .eq(ShopActivityInstance::getShopId, ShopModuleTokenDataProvider.getShopId())
                .eq(ShopActivityInstance::getActivityId, ActivityType.SUPER_MEMBER_COUPON.getCode());
        this.remove(exitDivineVoucherWrapper);
        if (isParticipate) {
            ShopActivityInstance shopActivityInstance = new ShopActivityInstance();
            shopActivityInstance.setActivityId(ActivityType.SUPER_MEMBER_COUPON.getCode());
            shopActivityInstance.setShopId(ShopModuleTokenDataProvider.getShopId());
            shopActivityInstance.setStartDate(LocalDateTime.now());
            shopActivityInstance.setTitle(ActivityType.SUPER_MEMBER_COUPON.getName());
            boolean isSaveSuccess = this.save(shopActivityInstance);
            if (!isSaveSuccess) {
                throw new RuntimeException("参与神券活动失败！");
            }
        }
    }

    @Override
    public boolean isShopInvolvedInPlatformCouponActivity(Long shopId) {
        // 查询店铺是否授权神券
        LambdaQueryWrapper<ShopActivityInstance> isParticipatingInPlatformInflationCouponActivityQueryWrapper = Wrappers.lambdaQuery(ShopActivityInstance.class)
                .eq(ShopActivityInstance::getShopId, shopId)
                .eq(ShopActivityInstance::getActivityId, ActivityType.SUPER_MEMBER_COUPON.getCode());
        // 店铺是否参与了平台膨胀券活动
        return this.count(isParticipatingInPlatformInflationCouponActivityQueryWrapper) > 0;
    }


    /**
     * 生成配送费活动名称
     * @param reduceDeliveryFreeActivityDTO
     * @return
     */
    private String generateReduceDeliveryFreeActivityName(ReduceDeliveryFreeActivityDTO reduceDeliveryFreeActivityDTO) {
        if (Objects.equals(ReduceValueType.BY_AMOUNT.getCode(), reduceDeliveryFreeActivityDTO.getValueType())) {
            return "立减配送费"+reduceDeliveryFreeActivityDTO.getValue()+"元";
        }
        List<Double> thresholds = Arrays.stream(reduceDeliveryFreeActivityDTO.getThreshold().split(",")).map(Double::valueOf).collect(Collectors.toList());
        List<Double> values = Arrays.stream(reduceDeliveryFreeActivityDTO.getValue().split(",")).map(Double::valueOf).collect(Collectors.toList());
        SyncSort.sort(Double::compareTo, thresholds, values);
        List<String> itemTitles = new ArrayList<>();
        for (int i = 0; i < thresholds.size(); i++) {
            itemTitles.add(nf.format(thresholds.get(i))+"公里内减"+nf.format(values.get(i))+"元");
        }
        return String.join(ActivityConstant.INSTANCE_TITLE_GRADIENT_SEPARATOR,itemTitles);
    }

    private String generateFullReductionActivityName(FullReductionActivityDTO fullReductionActivityDTO) {
        List<Double> thresholds = Arrays.stream(fullReductionActivityDTO.getThreshold().split(",")).map(Double::valueOf).collect(Collectors.toList());
        List<Double> values = Arrays.stream(fullReductionActivityDTO.getValue().split(",")).map(Double::valueOf).collect(Collectors.toList());
        SyncSort.sort(Double::compareTo, thresholds, values);
        List<String> itemTitles = new ArrayList<>();
        for (int i = 0; i < thresholds.size(); i++) {
            itemTitles.add("满"+nf.format(thresholds.get(i))+"减"+nf.format(values.get(i)));
        }
        return String.join(ActivityConstant.INSTANCE_TITLE_GRADIENT_SEPARATOR,itemTitles);
    }

}
